1 /*
2  * This file is part of gtkD.
3  *
4  * gtkD is free software; you can redistribute it and/or modify
5  * it under the terms of the GNU Lesser General Public License
6  * as published by the Free Software Foundation; either version 3
7  * of the License, or (at your option) any later version, with
8  * some exceptions, please read the COPYING file.
9  *
10  * gtkD is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13  * GNU Lesser General Public License for more details.
14  *
15  * You should have received a copy of the GNU Lesser General Public License
16  * along with gtkD; if not, write to the Free Software
17  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110, USA
18  */
19 
20 // generated automatically - do not change
21 // find conversion definition on APILookup.txt
22 // implement new conversion functionalities on the wrap.utils pakage
23 
24 
25 module sourceview.SearchContext;
26 
27 private import gio.AsyncResultIF;
28 private import gio.Cancellable;
29 private import glib.ConstructionException;
30 private import glib.ErrorG;
31 private import glib.GException;
32 private import glib.MemorySlice;
33 private import glib.Str;
34 private import gobject.ObjectG;
35 private import gtk.TextIter;
36 private import sourceview.Buffer;
37 private import sourceview.SearchSettings;
38 private import sourceview.Style;
39 private import sourceview.c.functions;
40 public  import sourceview.c.types;
41 
42 
43 /**
44  * Search context.
45  * 
46  * A `GtkSourceSearchContext` is used for the search and replace in a
47  * [class@Buffer]. The search settings are represented by a
48  * [class@SearchSettings] object. There can be a many-to-many relationship
49  * between buffers and search settings, with the search contexts in-between: a
50  * search settings object can be shared between several search contexts; and a
51  * buffer can contain several search contexts at the same time.
52  * 
53  * The total number of search occurrences can be retrieved with
54  * [method@SearchContext.get_occurrences_count]. To know the position of a
55  * certain match, use [method@SearchContext.get_occurrence_position].
56  * 
57  * The buffer is scanned asynchronously, so it doesn't block the user interface.
58  * For each search, the buffer is scanned at most once. After that, navigating
59  * through the occurrences doesn't require to re-scan the buffer entirely.
60  * 
61  * To search forward, use [method@SearchContext.forward] or
62  * [method@SearchContext.forward_async] for the asynchronous version.
63  * The backward search is done similarly. To replace a search match, or all
64  * matches, use [method@SearchContext.replace] and
65  * [method@SearchContext.replace_all].
66  * 
67  * The search occurrences are highlighted by default. To disable it, use
68  * [method@SearchContext.set_highlight]. You can enable the search
69  * highlighting for several `GtkSourceSearchContext`s attached to the
70  * same buffer. Moreover, each of those `GtkSourceSearchContext`s can
71  * have a different text style associated. Use
72  * [method@SearchContext.set_match_style] to specify the [class@Style]
73  * to apply on search matches.
74  * 
75  * Note that the [property@SearchContext:highlight] and
76  * [property@SearchContext:match-style] properties are in the
77  * `GtkSourceSearchContext` class, not [class@SearchSettings]. Appearance
78  * settings should be tied to one, and only one buffer, as different buffers can
79  * have different style scheme associated (a [class@SearchSettings] object
80  * can be bound indirectly to several buffers).
81  * 
82  * The concept of "current match" doesn't exist yet. A way to highlight
83  * differently the current match is to select it.
84  * 
85  * A search occurrence's position doesn't depend on the cursor position or other
86  * parameters. Take for instance the buffer "aaaa" with the search text "aa".
87  * The two occurrences are at positions [0:2] and [2:4]. If you begin to search
88  * at position 1, you will get the occurrence [2:4], not [1:3]. This is a
89  * prerequisite for regular expression searches. The pattern ".*" matches the
90  * entire line. If the cursor is at the middle of the line, you don't want the
91  * rest of the line as the occurrence, you want an entire line. (As a side note,
92  * regular expression searches can also match multiple lines.)
93  * 
94  * In the GtkSourceView source code, there is an example of how to use the
95  * search and replace API: see the tests/test-search.c file. It is a mini
96  * application for the search and replace, with a basic user interface.
97  */
98 public class SearchContext : ObjectG
99 {
100 	/** the main Gtk struct */
101 	protected GtkSourceSearchContext* gtkSourceSearchContext;
102 
103 	/** Get the main Gtk struct */
104 	public GtkSourceSearchContext* getSearchContextStruct(bool transferOwnership = false)
105 	{
106 		if (transferOwnership)
107 			ownedRef = false;
108 		return gtkSourceSearchContext;
109 	}
110 
111 	/** the main Gtk struct as a void* */
112 	protected override void* getStruct()
113 	{
114 		return cast(void*)gtkSourceSearchContext;
115 	}
116 
117 	/**
118 	 * Sets our main struct and passes it to the parent class.
119 	 */
120 	public this (GtkSourceSearchContext* gtkSourceSearchContext, bool ownedRef = false)
121 	{
122 		this.gtkSourceSearchContext = gtkSourceSearchContext;
123 		super(cast(GObject*)gtkSourceSearchContext, ownedRef);
124 	}
125 
126 
127 	/** */
128 	public static GType getType()
129 	{
130 		return gtk_source_search_context_get_type();
131 	}
132 
133 	/**
134 	 * Creates a new search context, associated with @buffer, and customized with
135 	 * @settings.
136 	 *
137 	 * If @settings is %NULL, a new [class@SearchSettings] object will
138 	 * be created, that you can retrieve with [method@SearchContext.get_settings].
139 	 *
140 	 * Params:
141 	 *     buffer = a #GtkSourceBuffer.
142 	 *     settings = a #GtkSourceSearchSettings, or %NULL.
143 	 *
144 	 * Returns: a new search context.
145 	 *
146 	 * Throws: ConstructionException GTK+ fails to create the object.
147 	 */
148 	public this(Buffer buffer, SearchSettings settings)
149 	{
150 		auto __p = gtk_source_search_context_new((buffer is null) ? null : buffer.getBufferStruct(), (settings is null) ? null : settings.getSearchSettingsStruct());
151 
152 		if(__p is null)
153 		{
154 			throw new ConstructionException("null returned by new");
155 		}
156 
157 		this(cast(GtkSourceSearchContext*) __p, true);
158 	}
159 
160 	/**
161 	 * Synchronous backward search.
162 	 *
163 	 * It is recommended to use the asynchronous functions instead, to not block the user interface.
164 	 * However, if you are sure that the @buffer is small, this function is more convenient to use.
165 	 *
166 	 * If the [property@SearchSettings:wrap-around] property is %FALSE, this function
167 	 * doesn't try to wrap around.
168 	 *
169 	 * The @has_wrapped_around out parameter is set independently of whether a match
170 	 * is found. So if this function returns %FALSE, @has_wrapped_around will have
171 	 * the same value as the [property@SearchSettings:wrap-around] property.
172 	 *
173 	 * Params:
174 	 *     iter = start of search.
175 	 *     matchStart = return location for start of match, or %NULL.
176 	 *     matchEnd = return location for end of match, or %NULL.
177 	 *     hasWrappedAround = return location to know whether the
178 	 *         search has wrapped around, or %NULL.
179 	 *
180 	 * Returns: whether a match was found.
181 	 */
182 	public bool backward(TextIter iter, out TextIter matchStart, out TextIter matchEnd, out bool hasWrappedAround)
183 	{
184 		GtkTextIter* outmatchStart = sliceNew!GtkTextIter();
185 		GtkTextIter* outmatchEnd = sliceNew!GtkTextIter();
186 		int outhasWrappedAround;
187 
188 		auto __p = gtk_source_search_context_backward(gtkSourceSearchContext, (iter is null) ? null : iter.getTextIterStruct(), outmatchStart, outmatchEnd, &outhasWrappedAround) != 0;
189 
190 		matchStart = ObjectG.getDObject!(TextIter)(outmatchStart, true);
191 		matchEnd = ObjectG.getDObject!(TextIter)(outmatchEnd, true);
192 		hasWrappedAround = (outhasWrappedAround == 1);
193 
194 		return __p;
195 	}
196 
197 	/**
198 	 * The asynchronous version of [method@SearchContext.backward].
199 	 *
200 	 * See the [iface@Gio.AsyncResult] documentation to know how to use this function.
201 	 *
202 	 * If the operation is cancelled, the @callback will only be called if
203 	 * @cancellable was not %NULL. The method takes
204 	 * ownership of @cancellable, so you can unref it after calling this function.
205 	 *
206 	 * Params:
207 	 *     iter = start of search.
208 	 *     cancellable = a #GCancellable, or %NULL.
209 	 *     callback = a #GAsyncReadyCallback to call when the operation is finished.
210 	 *     userData = the data to pass to the @callback function.
211 	 */
212 	public void backwardAsync(TextIter iter, Cancellable cancellable, GAsyncReadyCallback callback, void* userData)
213 	{
214 		gtk_source_search_context_backward_async(gtkSourceSearchContext, (iter is null) ? null : iter.getTextIterStruct(), (cancellable is null) ? null : cancellable.getCancellableStruct(), callback, userData);
215 	}
216 
217 	/**
218 	 * Finishes a backward search started with
219 	 * [method@SearchContext.backward_async].
220 	 *
221 	 * See the documentation of [method@SearchContext.backward] for more
222 	 * details.
223 	 *
224 	 * Params:
225 	 *     result = a #GAsyncResult.
226 	 *     matchStart = return location for start of match, or %NULL.
227 	 *     matchEnd = return location for end of match, or %NULL.
228 	 *     hasWrappedAround = return location to know whether the
229 	 *         search has wrapped around, or %NULL.
230 	 *
231 	 * Returns: whether a match was found.
232 	 *
233 	 * Throws: GException on failure.
234 	 */
235 	public bool backwardFinish(AsyncResultIF result, out TextIter matchStart, out TextIter matchEnd, out bool hasWrappedAround)
236 	{
237 		GtkTextIter* outmatchStart = sliceNew!GtkTextIter();
238 		GtkTextIter* outmatchEnd = sliceNew!GtkTextIter();
239 		int outhasWrappedAround;
240 		GError* err = null;
241 
242 		auto __p = gtk_source_search_context_backward_finish(gtkSourceSearchContext, (result is null) ? null : result.getAsyncResultStruct(), outmatchStart, outmatchEnd, &outhasWrappedAround, &err) != 0;
243 
244 		if (err !is null)
245 		{
246 			throw new GException( new ErrorG(err) );
247 		}
248 
249 		matchStart = ObjectG.getDObject!(TextIter)(outmatchStart, true);
250 		matchEnd = ObjectG.getDObject!(TextIter)(outmatchEnd, true);
251 		hasWrappedAround = (outhasWrappedAround == 1);
252 
253 		return __p;
254 	}
255 
256 	/**
257 	 * Synchronous forward search.
258 	 *
259 	 * It is recommended to use the asynchronous functions instead, to not block the user interface.
260 	 * However, if you are sure that the @buffer is small, this function is more convenient to use.
261 	 *
262 	 * If the [property@SearchSettings:wrap-around] property is %FALSE, this function
263 	 * doesn't try to wrap around.
264 	 *
265 	 * The @has_wrapped_around out parameter is set independently of whether a match
266 	 * is found. So if this function returns %FALSE, @has_wrapped_around will have
267 	 * the same value as the  [property@SearchSettings:wrap-around] property.
268 	 *
269 	 * Params:
270 	 *     iter = start of search.
271 	 *     matchStart = return location for start of match, or %NULL.
272 	 *     matchEnd = return location for end of match, or %NULL.
273 	 *     hasWrappedAround = return location to know whether the
274 	 *         search has wrapped around, or %NULL.
275 	 *
276 	 * Returns: whether a match was found.
277 	 */
278 	public bool forward(TextIter iter, out TextIter matchStart, out TextIter matchEnd, out bool hasWrappedAround)
279 	{
280 		GtkTextIter* outmatchStart = sliceNew!GtkTextIter();
281 		GtkTextIter* outmatchEnd = sliceNew!GtkTextIter();
282 		int outhasWrappedAround;
283 
284 		auto __p = gtk_source_search_context_forward(gtkSourceSearchContext, (iter is null) ? null : iter.getTextIterStruct(), outmatchStart, outmatchEnd, &outhasWrappedAround) != 0;
285 
286 		matchStart = ObjectG.getDObject!(TextIter)(outmatchStart, true);
287 		matchEnd = ObjectG.getDObject!(TextIter)(outmatchEnd, true);
288 		hasWrappedAround = (outhasWrappedAround == 1);
289 
290 		return __p;
291 	}
292 
293 	/**
294 	 * The asynchronous version of [method@SearchContext.forward].
295 	 *
296 	 * See the [iface@Gio.AsyncResult] documentation to know how to use this function.
297 	 *
298 	 * If the operation is cancelled, the @callback will only be called if
299 	 * @cancellable was not %NULL. The method takes
300 	 * ownership of @cancellable, so you can unref it after calling this function.
301 	 *
302 	 * Params:
303 	 *     iter = start of search.
304 	 *     cancellable = a #GCancellable, or %NULL.
305 	 *     callback = a #GAsyncReadyCallback to call when the operation is finished.
306 	 *     userData = the data to pass to the @callback function.
307 	 */
308 	public void forwardAsync(TextIter iter, Cancellable cancellable, GAsyncReadyCallback callback, void* userData)
309 	{
310 		gtk_source_search_context_forward_async(gtkSourceSearchContext, (iter is null) ? null : iter.getTextIterStruct(), (cancellable is null) ? null : cancellable.getCancellableStruct(), callback, userData);
311 	}
312 
313 	/**
314 	 * Finishes a forward search started with [method@SearchContext.forward_async].
315 	 *
316 	 * See the documentation of [method@SearchContext.forward] for more
317 	 * details.
318 	 *
319 	 * Params:
320 	 *     result = a #GAsyncResult.
321 	 *     matchStart = return location for start of match, or %NULL.
322 	 *     matchEnd = return location for end of match, or %NULL.
323 	 *     hasWrappedAround = return location to know whether the
324 	 *         search has wrapped around, or %NULL.
325 	 *
326 	 * Returns: whether a match was found.
327 	 *
328 	 * Throws: GException on failure.
329 	 */
330 	public bool forwardFinish(AsyncResultIF result, out TextIter matchStart, out TextIter matchEnd, out bool hasWrappedAround)
331 	{
332 		GtkTextIter* outmatchStart = sliceNew!GtkTextIter();
333 		GtkTextIter* outmatchEnd = sliceNew!GtkTextIter();
334 		int outhasWrappedAround;
335 		GError* err = null;
336 
337 		auto __p = gtk_source_search_context_forward_finish(gtkSourceSearchContext, (result is null) ? null : result.getAsyncResultStruct(), outmatchStart, outmatchEnd, &outhasWrappedAround, &err) != 0;
338 
339 		if (err !is null)
340 		{
341 			throw new GException( new ErrorG(err) );
342 		}
343 
344 		matchStart = ObjectG.getDObject!(TextIter)(outmatchStart, true);
345 		matchEnd = ObjectG.getDObject!(TextIter)(outmatchEnd, true);
346 		hasWrappedAround = (outhasWrappedAround == 1);
347 
348 		return __p;
349 	}
350 
351 	/**
352 	 * Returns: the associated buffer.
353 	 */
354 	public Buffer getBuffer()
355 	{
356 		auto __p = gtk_source_search_context_get_buffer(gtkSourceSearchContext);
357 
358 		if(__p is null)
359 		{
360 			return null;
361 		}
362 
363 		return ObjectG.getDObject!(Buffer)(cast(GtkSourceBuffer*) __p);
364 	}
365 
366 	/**
367 	 * Returns: whether to highlight the search occurrences.
368 	 */
369 	public bool getHighlight()
370 	{
371 		return gtk_source_search_context_get_highlight(gtkSourceSearchContext) != 0;
372 	}
373 
374 	/**
375 	 * Returns: the #GtkSourceStyle to apply on search matches.
376 	 */
377 	public Style getMatchStyle()
378 	{
379 		auto __p = gtk_source_search_context_get_match_style(gtkSourceSearchContext);
380 
381 		if(__p is null)
382 		{
383 			return null;
384 		}
385 
386 		return ObjectG.getDObject!(Style)(cast(GtkSourceStyle*) __p);
387 	}
388 
389 	/**
390 	 * Gets the position of a search occurrence.
391 	 *
392 	 * If the buffer is not already fully scanned, the position may be unknown,
393 	 * and -1 is returned. If 0 is returned, it means that this part of the buffer
394 	 * has already been scanned, and that @match_start and @match_end don't delimit an occurrence.
395 	 *
396 	 * Params:
397 	 *     matchStart = the start of the occurrence.
398 	 *     matchEnd = the end of the occurrence.
399 	 *
400 	 * Returns: the position of the search occurrence. The first occurrence has the
401 	 *     position 1 (not 0). Returns 0 if @match_start and @match_end don't delimit
402 	 *     an occurrence. Returns -1 if the position is not yet known.
403 	 */
404 	public int getOccurrencePosition(TextIter matchStart, TextIter matchEnd)
405 	{
406 		return gtk_source_search_context_get_occurrence_position(gtkSourceSearchContext, (matchStart is null) ? null : matchStart.getTextIterStruct(), (matchEnd is null) ? null : matchEnd.getTextIterStruct());
407 	}
408 
409 	/**
410 	 * Gets the total number of search occurrences.
411 	 *
412 	 * If the buffer is not already fully scanned, the total number of occurrences is
413 	 * unknown, and -1 is returned.
414 	 *
415 	 * Returns: the total number of search occurrences, or -1 if unknown.
416 	 */
417 	public int getOccurrencesCount()
418 	{
419 		return gtk_source_search_context_get_occurrences_count(gtkSourceSearchContext);
420 	}
421 
422 	/**
423 	 * Regular expression patterns must follow certain rules. If
424 	 * [property@SearchSettings:search-text] breaks a rule, the error can be
425 	 * retrieved with this function.
426 	 *
427 	 * The error domain is [enum@GLib.RegexError].
428 	 *
429 	 * Free the return value with [method@GLib.Error.free].
430 	 *
431 	 * Returns: the #GError, or %NULL if the
432 	 *     pattern is valid.
433 	 */
434 	public ErrorG getRegexError()
435 	{
436 		auto __p = gtk_source_search_context_get_regex_error(gtkSourceSearchContext);
437 
438 		if(__p is null)
439 		{
440 			return null;
441 		}
442 
443 		return new ErrorG(cast(GError*) __p, true);
444 	}
445 
446 	/**
447 	 * Returns: the search settings.
448 	 */
449 	public SearchSettings getSettings()
450 	{
451 		auto __p = gtk_source_search_context_get_settings(gtkSourceSearchContext);
452 
453 		if(__p is null)
454 		{
455 			return null;
456 		}
457 
458 		return ObjectG.getDObject!(SearchSettings)(cast(GtkSourceSearchSettings*) __p);
459 	}
460 
461 	/**
462 	 * Replaces a search match by another text. If @match_start and @match_end
463 	 * doesn't correspond to a search match, %FALSE is returned.
464 	 *
465 	 * @match_start and @match_end iters are revalidated to point to the replacement
466 	 * text boundaries.
467 	 *
468 	 * For a regular expression replacement, you can check if @replace is valid by
469 	 * calling [func@GLib.Regex.check_replacement]. The @replace text can contain
470 	 * backreferences.
471 	 *
472 	 * Params:
473 	 *     matchStart = the start of the match to replace.
474 	 *     matchEnd = the end of the match to replace.
475 	 *     replace = the replacement text.
476 	 *     replaceLength = the length of @replace in bytes, or -1.
477 	 *
478 	 * Returns: whether the match has been replaced.
479 	 *
480 	 * Throws: GException on failure.
481 	 */
482 	public bool replace(TextIter matchStart, TextIter matchEnd, string replace, int replaceLength)
483 	{
484 		GError* err = null;
485 
486 		auto __p = gtk_source_search_context_replace(gtkSourceSearchContext, (matchStart is null) ? null : matchStart.getTextIterStruct(), (matchEnd is null) ? null : matchEnd.getTextIterStruct(), Str.toStringz(replace), replaceLength, &err) != 0;
487 
488 		if (err !is null)
489 		{
490 			throw new GException( new ErrorG(err) );
491 		}
492 
493 		return __p;
494 	}
495 
496 	/**
497 	 * Replaces all search matches by another text.
498 	 *
499 	 * It is a synchronous function, so it can block the user interface.
500 	 *
501 	 * For a regular expression replacement, you can check if @replace is valid by
502 	 * calling [func@GLib.Regex.check_replacement]. The @replace text can contain
503 	 * backreferences.
504 	 *
505 	 * Params:
506 	 *     replace = the replacement text.
507 	 *     replaceLength = the length of @replace in bytes, or -1.
508 	 *
509 	 * Returns: the number of replaced matches.
510 	 *
511 	 * Throws: GException on failure.
512 	 */
513 	public uint replaceAll(string replace, int replaceLength)
514 	{
515 		GError* err = null;
516 
517 		auto __p = gtk_source_search_context_replace_all(gtkSourceSearchContext, Str.toStringz(replace), replaceLength, &err);
518 
519 		if (err !is null)
520 		{
521 			throw new GException( new ErrorG(err) );
522 		}
523 
524 		return __p;
525 	}
526 
527 	/**
528 	 * Enables or disables the search occurrences highlighting.
529 	 *
530 	 * Params:
531 	 *     highlight = the setting.
532 	 */
533 	public void setHighlight(bool highlight)
534 	{
535 		gtk_source_search_context_set_highlight(gtkSourceSearchContext, highlight);
536 	}
537 
538 	/**
539 	 * Set the style to apply on search matches.
540 	 *
541 	 * If @match_style is %NULL, default theme's scheme 'match-style' will be used.
542 	 * To enable or disable the search highlighting, use [method@SearchContext.set_highlight].
543 	 *
544 	 * Params:
545 	 *     matchStyle = a #GtkSourceStyle, or %NULL.
546 	 */
547 	public void setMatchStyle(Style matchStyle)
548 	{
549 		gtk_source_search_context_set_match_style(gtkSourceSearchContext, (matchStyle is null) ? null : matchStyle.getStyleStruct());
550 	}
551 }